# -*- coding: utf-8 -*-
"""
@Time ： 2021/5/19 17:03
@Auth ： Mr. royalday 2487625775
@Company ：XXX
@Function ：文件管理的modelform
"""
from django import forms
from web.forms.bootstrap import BootStrapForm
from web import models
from django.core.exceptions import ValidationError
from utils.tencent.cos import check_file


class FolderModelForm(BootStrapForm, forms.ModelForm):
    """
    文件夹表单
    """

    def __init__(self, request, parent_object, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.request = request
        self.parent_object = parent_object

    class Meta:
        model = models.FileRepository
        # 新增文件夹时只需要输入文件夹名称就行了
        fields = ['file_name']

    def clean_file_name(self):
        """
        文件夹名称的钩子,条件:同一父目录下不能有同名的文件夹存在
        :return: file_name 文件夹名称
        """
        file_name = self.cleaned_data['file_name']

        # 有两种情况,第一个是根目录,此时parent_object为None,第一个是有父目录parent_object不为空
        # 先拿到所有跟当前文件夹名称同名的记录
        queryset = models.FileRepository.objects.filter(
            file_type=2, file_name=file_name, project=self.request.tracer.project)
        # 判断传入的父目录对象是否为 None
        if self.parent_object:
            # 如果为None,则说明当前路径是根目录,直接判断是否会与当前文件夹名称同名
            exists = queryset.filter(parent=self.parent_object).exists()
        else:
            # 否则说明不在根目录,需要判断父目录为parent_object下的所有文件是会与当前文件夹名称否存在同名现象
            exists = queryset.filter(parent__isnull=True).exists()
        # 如果存在同名目录,则报错,否则返回文件夹名称
        if exists:
            raise ValidationError("文件夹已存在")
        return file_name


class FileModelForm(forms.ModelForm):
    ETag = forms.CharField(label="ETag")

    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.request = request

    class Meta:
        model = models.FileRepository
        fields = ["file_name", "key_name", "file_size", "file_path", "parent"]

    def clean_file_path(self):
        return f"https://{self.cleaned_data['file_path']}"

    def clean(self):
        key_name = self.cleaned_data['key_name']
        ETag = self.cleaned_data['ETag']
        file_size = self.cleaned_data['file_size']
        if not key_name or not ETag:
            return self.cleaned_data

        # 向cos校验文件是否合法
        from qcloud_cos.cos_exception import CosServiceError
        try:
            result = check_file(bucket=self.request.tracer.project.bucket,
                                key=key_name,
                                region=self.request.tracer.project.region)
        except CosServiceError as e:
            self.add_error(key_name, "文件不存在")

        cos_etag = result.get("ETag")
        if ETag != cos_etag:
            self.add_error("ETag", "ETag错误")

        cos_length = eval(result.get("Content-Length"))
        if file_size != cos_length:
            self.add_error("file_size", "文件大小不一致")


